drawArc + Thread 원 그리기
ㆍ 이번글은 지난글 마지막에 말했던 drawArc와 Thread를 이용해서 실시간 원을 그리는 방법에 대해 알아보도록 하겠습니다.
ㆍ drawArc 사용방법은 지난글에서 알아보았으니 간단하게 코드위주로 보고 끝내도록 하겠습니다.
간단하게 위에 처럼 만들어보겠습니다.
원리만 알면 쉽게 컨츄럴 해서 다양하게 사용 가능합니다
바로 시작해보겠습니다 (이전글 안보신분들은 꼭 보시길!!)
canvas.drawArc(rect, 270, i, false, pnt);
이 부분만 잘 보면 되겠죠?
270도가 시작지점이고, i위치가 몇도를 돌릴것인지 결정하므로 i에 1을 넣게 되면 270도에서 271도까지 돌리는거겠죠? 그 다음 i에 2를 넣게 되면 270도에서 272도까지 돌리는거겠죠?
자 그럼 Thread를 돌려서 n초 마다 i값을 증가시켜주면 간단하게 끝납니다.
코드를 보겠습니다.
먼저, 앱을 실행하면 바로 서브스레드를 실행시킵니다. MyView myView; Thread myThread; MyRunnable myRunnable; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); myView = (MyView)findViewById(R.id.myView); startSubThread(); } public void startSubThread() { myRunnable = new MyRunnable(); myThread = new Thread(myRunnable); myThread.setDaemon(true); myThread.start(); }
그 다음 Handler와 Runnable을 보면 android.os.Handler mainHandler = new android.os.Handler() { public void handleMessage(Message msg) { if (msg.what == 0) { myView.invalidate(); } } };
public class MyRunnable implements Runnable { @Override public void run() { while(mainHandler!=null) { try { myView.i = myView.i + 0.6f; Message msg = Message.obtain(); msg.what = 0; mainHandler.sendMessage(msg); } catch (Exception e) { e.printStackTrace(); }
try { Thread.sleep(10); } catch (Exception e) { e.printStackTrace(); } } } }
myView.i = myView.i + 0.6f; drawArc 들어가는 i값을 0.6씩 증가시킵니다
Thread.sleep(10); 1000이 1초이므로 0.01초마다 증가하겠죠?
myView.invalidate(); 0.01초마다 invalidate() 해줍니다. invalidate()를 써주면 커스텀뷰의 onDraw()가 실행됩니다.
그 다음은 MyView를 볼까요? @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Paint pnt = new Paint(); pnt.setStrokeWidth(6f); pnt.setColor(Color.parseColor("#FF0000")); pnt.setStyle(Paint.Style.STROKE);
RectF rect = new RectF(); rect.set(200, (200), 600, 600); canvas.drawArc(rect, 270, i, false, pnt); } 이 부분이 0.01초마다 호출되는 부분입니다.
canvas.drawArc(rect, 270, i, false, pnt);
i값이 0.01초마다 0.6씩 증가합니다.
자 이렇게 되면 270 -> 270.6 270 -> 271.2 270 -> 271.8 270 -> 272.4 이런식으로 엄청 빠르게 진행되겠죠?
자 그럼 만약 반시계반향으로 진행하려면 어떻게 할까요?
써보면서 생각하면 쉽습니다. 269.4 -> 270 268.8 -> 270 268.6 -> 270 이런식으로 drawArc가 시계반향으로 진행되므로 끝점인 270은 고정시키고 시작점을 아에 0.6씩 빼버리면 되겠죠?
canvas.drawArc(rect, (270-i), i, false, pnt);
이렇게 써 넣으면 되겠죠?
그럼 전체 코드를 보면서 마무리 하겠습니다. (코드는 정리하고 수정해서 쓰세요 ㅎㅎ 너무 대충 짜서 .ㅠㅠ)
[MainActivity] public class MainActivity extends AppCompatActivity { MyView myView; Thread myThread; MyRunnable myRunnable; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); myView = (MyView)findViewById(R.id.myView); startSubThread(); } public void startSubThread() { myRunnable = new MyRunnable(); myThread = new Thread(myRunnable); myThread.setDaemon(true); myThread.start(); }
android.os.Handler mainHandler = new android.os.Handler() { public void handleMessage(Message msg) { if (msg.what == 0) { myView.invalidate(); } } };
public class MyRunnable implements Runnable { @Override public void run() { while(mainHandler!=null) { try { myView.i = myView.i + 0.6f; Message msg = Message.obtain(); msg.what = 0; mainHandler.sendMessage(msg); } catch (Exception e) { e.printStackTrace(); }
try { Thread.sleep(10); } catch (Exception e) { e.printStackTrace(); } } } } }
[MyView] public class MyView extends View { float i; public MyView(Context context, AttributeSet attrs) { super(context, attrs); }
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Paint pnt = new Paint(); pnt.setStrokeWidth(6f); pnt.setColor(Color.parseColor("#FF0000")); pnt.setStyle(Paint.Style.STROKE);
RectF rect = new RectF(); rect.set(200, (200), 600, 600); canvas.drawArc(rect, 270, i, false, pnt);
pnt.setColor(Color.parseColor("#2F9D27")); rect = new RectF(); rect.set(200, (700), 600, 1100); canvas.drawArc(rect, (270-i), i, false, pnt); } }
끝!!!
출처: http://itpangpang.xyz/322 [ITPangPang] |